<?php

namespace App\Console\Commands\Fix;

use App\Common\Libs\Ali\Oss;
use App\Common\Libs\Json;
use App\Console\BaseCommand;
use App\Consts\GlobalConst;
use App\Consts\GlobalUploadConst;
use App\Models\UserMessageLikeReceive;
use Illuminate\Database\Query\Builder;

/**
 * 点赞 OSS 文件修复
 * Class LikeFixCommand
 * @package App\Console\Commands\Fix
 */
class OssLikeFixCommand extends BaseCommand
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fix:oss-like {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'fix like static message to oss';

    /**
     * 消息静态化 - 收到的点赞
     * @return int
     */
    public function receive()
    {
        $subMode = $this->_getSubModel();
        $finish = $subMode->count();
        // 每 100 单位合并处理一次
        $subMode->chunkById(100, function ($list) use ($finish) {
            foreach ($list as $item) {
                static $index = 1;
                $messageId = $item->message_id;
                $userId = $item->receive_id;
                // 跳过自己的
                if ($item->receive_id == $item->sender_id) {
                    continue;
                }
                // get oss data
                $data = Oss::getInstance(GlobalUploadConst::OBJECT_LIKE_MSG_RECEIVE)
                    ->getObject($userId . '/'. $messageId . '.json');
                $json = Json::decode($data, false);
                // get static data
                $message = UserMessageLikeReceive::getModel($userId)->where(['message_id' => $messageId])->first();
                $data = $this->_getStaticData($message);
                // 数据内容不同，重新上传
                if (Json::encode($json) != Json::encode((object)$data)) {
                    $res = false;
                    // set oss file
                    if ($data) {
                        $res = Oss::getInstance(GlobalUploadConst::OBJECT_LIKE_MSG_RECEIVE . $userId . '/')
                            ->uploadTarget($data);
                    }
                    // log info
                    if (!$res) $this->logger('upload to oss failed - '. json_encode($data), true, 'script');
                    $res = $res ? 'SUCCESS' : 'FAILED';
                    $info = "[$index/$finish] generate oss file [like/receive] [$res] [".env('APP_ENV')."] : "
                        .GlobalUploadConst::OBJECT_LIKE_MSG_RECEIVE."$userId/$messageId.json .";
                    $this->logger($info, true, 'script');
                } else {
                    $info = "[$index/$finish] check oss file [like/receive] : " ."$userId/$messageId.json .";
                    $this->info($info);
                }
                $index++;
            }
        }, 'message_id');
        return 1;
    }

    /**
     * 获取静态数据
     * @param UserMessageLikeReceive $message
     * @return array
     */
    private static function _getStaticData($message)
    {
        $result = [];
        $target = [];
        $articleService = service()->ArticleService;
        $noteService = service()->NoteService;
        $userService = service()->UserService;
        if ($message->target_type == GlobalConst::TARGET_TYPE_NOTE ) {
            $note['note'] = $noteService->getNoteOne($message->target_id);
            $note['target_type'] = GlobalConst::TARGET_TYPE_NOTE;
            if (!empty($note)){
                $result = [
                    'id' => $message->message_id,
                    'created_at' => $message->created_at,
                    'main' => [
                        'target_type' => GlobalConst::TARGET_TYPE_NOTE,
                    ],
                    'target' => $note,
                    'child' => (object)[],

                ];
            }
        }
        if ($message->target_type == GlobalConst::TARGET_TYPE_COMMENT && !empty($message->comment)) {
            $comment = $message->comment;
            if ($comment->target_type == GlobalConst::TARGET_TYPE_NOTE) {
                $target['note'] = $noteService->getNoteOne($comment->target_id);
                $target['target_type'] = GlobalConst::TARGET_TYPE_NOTE;
            }
            if ($comment->target_type == GlobalConst::TARGET_TYPE_DYNAMIC) {
                if (!empty($comment->dynamic)) {
                    if ($comment->dynamic->target_type == GlobalConst::TARGET_TYPE_ARTICLE) {
                        $article = $articleService->getArticleByArticleId($comment->dynamic->target_id);
                        $target['dynamic']['article'] = $article ? $article->toArray() : [];
                        $target['target_type'] = GlobalConst::TARGET_TYPE_DYNAMIC;
                        $target['dynamic']['id'] = $comment->dynamic->dynamic_id;
                        $target['dynamic']['type'] = $comment->dynamic->type;
                    }
                    if ($comment->dynamic->target_type == GlobalConst::TARGET_TYPE_NOTE) {
                        $target['dynamic'] = $noteService->getNoteOne($comment->dynamic->target_id);
                        $target['target_type'] = $comment->dynamic->target_type;
                        $target['dynamic']['type'] = $comment->dynamic->type;
                    }
                }
            }
            $result = [
                'id' => $message->message_id,
                'created_at' => $message->created_at,
                'main' =>[
                    'target_type' => GlobalConst::TARGET_TYPE_COMMENT,
                    'user' => $userService->getUserByUserId($comment->user_id),
                    'id' =>$comment->comment_id,
                    'content' =>$comment->content,
                ],
                'target' => $target
            ];
            $result['child'] = $result['main'];
        }
        if ($message->target_type == GlobalConst::TARGET_TYPE_REPLY && !empty($message->reply)) {
            $reply = $message->reply;
            if ($reply->target_type == GlobalConst::TARGET_TYPE_NOTE) {
                $target['note'] = $noteService->getNoteOne($reply->target_id);
                $target['target_type'] = GlobalConst::TARGET_TYPE_NOTE;
            }
            if ($reply->target_type == GlobalConst::TARGET_TYPE_DYNAMIC) {
                if (!empty($reply->dynamic)) {
                    if ($reply->dynamic->target_type == GlobalConst::TARGET_TYPE_ARTICLE) {
                        $article = $articleService->getArticleByArticleId($reply->dynamic->target_id);
                        $target['dynamic']['article'] = $article ? $article->toArray() : [];
                        $target['target_type'] = GlobalConst::TARGET_TYPE_DYNAMIC;
                        $target['dynamic']['id'] = $reply->dynamic->dynamic_id;
                        $target['dynamic']['type'] = $reply->dynamic->type;

                    }
                    if ($reply->dynamic->target_type == GlobalConst::TARGET_TYPE_NOTE) {
                        $target['dynamic'] = $noteService->getNoteOne($reply->dynamic->target_id);
                        $target['target_type'] = $reply->dynamic->target_type;
                        $target['dynamic']['type'] = $reply->dynamic->type;
                    }
                }
            }
            $result = [
                'id' => $message->message_id,
                'created_at' => $message->created_at,
                'main' => [
                    'id' =>$reply->reply_id,
                    'content' =>$reply->content,
                    'target_type' => GlobalConst::TARGET_TYPE_REPLY,
                    'user' => $userService->getUserByUserId($reply->user_id),
                    'to_user' => $userService->getUserByUserId($reply->to_user_id),
                ],
                'target' => $target
            ];
            unset($result['main']['to_user']);
            $result['child'] = $result['main'];
        }
        if ($message->target_type == GlobalConst::TARGET_TYPE_DYNAMIC && !empty($message->dynamic)) {
            if ($message->dynamic->target_type == GlobalConst::TARGET_TYPE_ARTICLE) {
                $article = $articleService->getArticleByArticleId($message->dynamic->target_id);
                $target['dynamic']['article'] = $article ? $article->toArray() : [];
                $target['target_type'] = GlobalConst::TARGET_TYPE_DYNAMIC;
                $target['dynamic']['id'] = $message->dynamic->dynamic_id;
                $target['dynamic']['type'] = $message->dynamic->type;
            }
            if ($message->dynamic->target_type == GlobalConst::TARGET_TYPE_NOTE) {
                $target['dynamic'] = $noteService->getNoteOne($message->dynamic->target_id);
                $target['target_type'] = $message->dynamic->target_type;
                $target['dynamic']['type'] = $message->dynamic->type;

            }
            $result = [
                'id' => $message->message_id,
                'created_at' => $message->created_at,
                'main' => [
                    'target_type' => GlobalConst::TARGET_TYPE_DYNAMIC,
                ],
                'target' => $target,
                'child' => (object)[],
            ];
        }
        if (empty($result['child'])){
            $result['child'] = (object)[];
        }
        if (empty($result['target'])){
            $result['target'] = (object)[];
        }
        return $result;
    }

    /**
     * get sub model
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|mixed
     */
    private function _getSubModel()
    {
        $subMode = UserMessageLikeReceive::getSubModel(function (Builder $query) {
            $query->where('message_id', '<>', '');
            $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
        }, ['id', 'message_id', 'receive_id', 'sender_id']);
        return $subMode;
    }

}
